package com.sky.module.support.crypt.aspect;

import com.alibaba.fastjson.JSON;
import com.sky.module.support.crypt.AESEncrypt;
import com.sky.module.support.crypt.annotation.JweDecrypt;
import com.sky.module.support.crypt.annotation.JweEncrypt;
import com.sky.module.support.crypt.config.AESConfig;
import com.sky.module.support.crypt.entity.DecryptData;
import com.sky.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;

/**
 * @author
 * @date 2023/3/11 18:52
 **/
@Slf4j
@Aspect
@Component
public class AESAspect {

    @Autowired
    private AESConfig aesConfig;


    /***
     * @description 切面前置通知
     * @param joinPoint
     * @return void
     * @date 2023/3/11 21:14
     *
     */
    @Before("@annotation(com.sky.module.support.crypt.annotation.JweDecrypt)")
    public void before(JoinPoint joinPoint) throws UnsupportedEncodingException {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        final JweDecrypt annotation = method.getAnnotation(JweDecrypt.class);
        if (annotation == null) {
            return;
        }
        Object[] params = joinPoint.getArgs();
        if (params == null) {
            return;
        }
        boolean flag = params[0] instanceof DecryptData;
        if (params.length == 0) {
            return;
        }
        DecryptData param = (DecryptData) params[0];
        String decrypt = AESEncrypt.decrypt(param.getData(), aesConfig.getKey(), "1234565");
        param.setData(decrypt);
        params[0] = param;
    }

    /***
     * @description 这个是切面的后置通知，object就是我们返回的对象
     *  然后 returning 的话就表示controller的返回值 因为是后置通知
     * @param joinPoint
     * @param object
     * @return void
     * @date 2023/3/11 21:17
     *
     */
    @AfterReturning(returning = "object", pointcut = "@annotation(com.sky.module.support.crypt.annotation.JweEncrypt)")
    public void after(JoinPoint joinPoint, Object object) {
        Method method = ((MethodSignature) joinPoint.getSignature()).getMethod();
        final JweEncrypt annotation = method.getAnnotation(JweEncrypt.class);
        if (annotation == null) {
            return;
        }
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//         TODO 登录校验

        Result result = (Result) object;
        Object data = result.getData();
        if (data == null) {
            return;
        }
        final String jsonString = JSON.toJSONString(data);
        String encrypt = null;
        try {
            // 加密
            encrypt = AESEncrypt.encrypt(jsonString, aesConfig.getKey(), "123456");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return;
        }
        result.setData(encrypt);
    }
}
